package com.webservice.ftp.utils;

import java.io.File;

import com.webservice.command.utils.CheckException;
import com.webservice.command.utils.Command;
import com.webservice.command.utils.FileUtil;
import com.webservice.command.utils.StringUtil;
import com.webservice.command.utils.TimeUtil;

/**
 * 获得要上传到FTP上的信息
 * @author 潘保涛
 *
 */
public class FtpDataOper {
	
	private Command command = new Command();
	
	private FileUtil fileUtil = new FileUtil();
	
	public byte[] zipCompress(String compressType, String commandString, String home, String subPath, String path){
		//获得zip压缩结果
		byte[] zipBytes = command.zipCompression(compressType, commandString, home, subPath, path);
		
		return zipBytes;
	}
	
	/**
	 * 获得数据的哈希结果
	 * @param compressType
	 * @param commandString
	 * @param home
	 * @param path
	 * @return
	 */
	public String dataHashOper(byte[] zipBytes, String hashType, String hashTypeCount, String messageKey){
		
		//hash加密
		String commandhash = command.hashAlgorithm(hashType, hashTypeCount, zipBytes, messageKey);
		
		//将结果base64加密的结果
//		String commandhash = StringUtil.getBaseByString(hashResult);
		
		return commandhash;
	}
	
	
	public String dataUploadOper(byte[] zipBytes, String encryptType, String aesKey, String aesOffsets){
		
		//对称加密
		byte[] encrypt = command.encryptAlgorithm(encryptType, zipBytes, aesKey, aesOffsets);
	
		// 对加密后的数据，进行base64编码
		String dataUpload = StringUtil.getBaseByByte(encrypt);
		
		return dataUpload;
	}

	
	/**
	 * 
	 * @return
	 */
	public String createFile(String filePath, String fileSubPath, String ftp_path, String fileContent, String curFileName){
		
		if (!filePath.endsWith(File.separator)) {
			filePath = filePath + File.separator;
        }
		if (!fileSubPath.endsWith(File.separator)) {
			fileSubPath = fileSubPath + File.separator;
        }
		if (!ftp_path.endsWith(File.separator)) {
			ftp_path = ftp_path + File.separator;
        }
		
		//创建上传文件在本地存放的目录
		String path = filePath + fileSubPath + ftp_path + TimeUtil.getDateString() + File.separator + TimeUtil.getTime();
		if (!path.endsWith(File.separator)) {
			path = path + File.separator;
        }
		
		
		fileUtil.createDirectory(path);
		
		String fileName = null;
		//获得上传文件的文件绝对路径名称
		if(curFileName == null || curFileName.trim().equals("")){
			fileName = path + TimeUtil.getTime() + ".upload";
		}else{
			fileName = path + curFileName + ".upload";
		}
		
		fileUtil.wirteFile(fileName, fileContent);
		
		return fileName;
	}
	
	/**
	 * 将指令内容上传到FTP上
	 * @param idcId 
	 * @param command 指令内容
	 * @param filePath 本地存放临时文件目录
	 * @param zip_path 本地存放临时文件目录下的子目录，与ftp上传目录相同，1,2,3...
	 * @param hashAlgorithm hash加密类型
	 * @param hashTypeCount hash加密长度
	 * @param compressionFormat zip压缩方式
	 * @param encryptAlgorithm 对称加密方式
	 * @param aesKey aesKey加密压缩
	 * @param aesOffsets 偏移量
	 * @param messageKey 消息认证钥匙
	 * @param ftpIP FTP_IP
	 * @param ftpUserName FTP_用户名
	 * @param ftpPwd FTP_密码
	 */
	public String fileUpload(String idcId, String command, String filePath, String zip_path, String fileName, 
			String hashAlgorithm, String hashTypeCount, String compressionFormat, 
			String encryptAlgorithm, String aesKey, String aesOffsets, String messageKey, 
			String ftpIP, String ftpUserName, String ftpPwd){
		//创建本地存储上传文件目录
		String fileSubPath = "upload";
		//创建本地生产zip文件的
		String zipSubPath = "zip";
		
		byte[] zipBytes = zipCompress(compressionFormat, command, filePath, zipSubPath, zip_path);
		String dataHash = this.dataHashOper(zipBytes, hashAlgorithm, hashTypeCount, messageKey);
		String dataUpload = this.dataUploadOper(zipBytes, encryptAlgorithm, aesKey, aesOffsets);
		
		//转换成xml字符串
		String fileContent = FileUploadXmlOper.createFileUploadFileXml(idcId, dataUpload, Integer.parseInt(encryptAlgorithm), Integer.parseInt(compressionFormat), Integer.parseInt(hashAlgorithm), dataHash);
		
		String uploadFileName = this.createFile(filePath, fileSubPath, zip_path, fileContent, fileName);
		
		FtpUpload.ftpUpload(uploadFileName, zip_path, ftpIP, ftpUserName, ftpPwd);
		
		return uploadFileName;
	}
	
	/**
	 * 解析ftp上的xml文件
	 * @param xmlContent
	 * @param aesKey
	 * @param aesOffsets
	 * @param hashTypeCount
	 * @param messageKey
	 * @return
	 */
	public String ftpFileOper(String xmlContent, String aesKey, String aesOffsets, String hashTypeCount, String messageKey) throws CheckException{
		String xmlInfo = null;
		FileUploadXml fileUploadXml = FileUploadXmlOper.parseFileUploadXmlFromString(xmlContent);
		//验证数据完整性
		String data_upload = fileUploadXml.getDataUpload();
		int hashAlgorithm = fileUploadXml.getHashAlgorithm();
		int encryptAlgorithm = fileUploadXml.getEncryptAlgorithm();
		int compressionFormat = fileUploadXml.getCompressionFormat();
		String dataHash = fileUploadXml.getDataHash();
		
		if(encryptAlgorithm !=0 && encryptAlgorithm != 1){
			throw new CheckException(errMessage("999", "对称加密算法参数异常，对称加密算法参数是:" + encryptAlgorithm));
		}else if(hashAlgorithm !=0 && hashAlgorithm != 1 && hashAlgorithm != 2){
			throw new CheckException(errMessage("999", "哈希算法参数异常，哈希算法参数是:" + hashAlgorithm));
		}else if(compressionFormat !=0 && compressionFormat != 1){
			throw new CheckException(errMessage("999", "压缩格式参数异常，压缩格式参数是:" + compressionFormat));
		}else{
			//base64解码
			byte[] dataArray = null;
			try{
				dataArray = StringUtil.getByteByBaseString(data_upload);
			}catch (Exception e) {
				e.printStackTrace();
				throw new CheckException(errMessage("999", "BASE64解码异常"));
			}
			
			try{
				dataArray = command.decryptAlgorithm(""+encryptAlgorithm, dataArray, aesKey, aesOffsets);
			}catch (Exception e) {
				e.printStackTrace();
				throw new CheckException(errMessage("1", "文件解密失败，对称加密算法参数是:" + encryptAlgorithm + "，加密密钥：" + aesKey + "，加密向量:" + aesOffsets));
			}
			
			String myDataHash = this.dataHashOper(dataArray, ""+hashAlgorithm, hashTypeCount, messageKey);
			if((dataHash != null && !dataHash.equals("") && myDataHash != null && myDataHash.equals(dataHash)) || (dataHash == null || dataHash.equals("")) || hashAlgorithm==0){
			
				try{
					xmlInfo = command.unZipCompression(""+compressionFormat, dataArray);
				}catch (Exception e) {
					e.printStackTrace();
					throw new CheckException(errMessage("3", "文件解压缩失败，压缩格式参数是:" + compressionFormat));
				}
			}else{
				throw new CheckException(errMessage("2", "文件校验失败，IDC侧dataHash:" + dataHash + "，SMCS侧dataHash:" + myDataHash));
			}
		}
		return xmlInfo;
	}
	
	public String errMessage(String errCode, String errMes){
		return errCode + "#" + errMes;
	}
	
	public String[] parseErrMessage(String errMessage){
		String[] errArray = null;
		if(errMessage.indexOf("#") != -1){
			errArray = errMessage.split("#");
		}
		return errArray;
	}
	
}
